package cmd_gen

import (
	"fmt"
	"gitee.com/xiakai001/goutl/animeutl"
	"gitee.com/xiakai001/goutl/errutl"
	"gitee.com/xiakai001/goutl/goutl"
	"github.com/urfave/cli/v2"
	"os"
	"path/filepath"
)

var MVCli = &cli.Command{

	Name:        "mv",
	Usage:       "check动漫mv",
	Description: "check动漫mv",

	Action: mvAction,
	Flags: []cli.Flag{
		mvPathFlag,
		mvCacheFlag,
	},
}

var mvPathFlag = &cli.StringFlag{
	Name:     "path",
	Aliases:  []string{"p"},
	Usage:    "动漫MV文件夹路径",
	Required: true,
}

var mvCacheFlag = &cli.StringFlag{
	Name:    "cache",
	Aliases: []string{"c"},
	Usage:   "动漫编码缓存",
}

type MVCache struct {
	VideoCodeStr string `json:"video_code_str"`
	AudioCodeStr string `json:"audio_code_str"`
}

func mvAction(ctx *cli.Context) error {

	dir := ctx.String("path")
	if len(dir) == 0 {
		return errutl.New("path is empty")
	}
	fileList, err := os.ReadDir(dir)
	if err != nil {
		return errutl.Wrap(err)
	}

	cacheDir := ctx.String("cache")
	cacheMap := map[string]*MVCache{}
	if len(cacheDir) != 0 {
		cacheMapPtr, err := goutl.LoadJsonFromFile[*map[string]*MVCache](cacheDir)
		if err != nil {
			return errutl.Wrap(err)
		}
		if cacheMapPtr != nil {
			cacheMap = *cacheMapPtr
		}
	}

	mvNameList := make([]string, 0, len(fileList))
	sizeMap := make(map[int64][]string, len(fileList))
	println("start code check!")
	for _, file := range fileList {
		if file.Name() == "desktop.ini" {
			continue
		}
		info, err := file.Info()
		if err != nil {
			return errutl.Wrap(err)
		}

		// 获取名字信息
		nameInfo, err := animeutl.GetMkvMVNameInfo(file.Name())
		if err != nil {
			fmt.Printf("mv_name:%s err=%s\n", file.Name(), errutl.Cause(err).Error())
			continue
		}

		fileFullPath := filepath.Join(dir, file.Name())
		dNameList, _ := sizeMap[info.Size()]
		for _, dName := range dNameList {
			// 判断是否重复
			if nameInfo.SongName == dName {
				fmt.Printf("mv_name:%s err=文件重复了\n", file.Name())
			}
		}
		sizeMap[info.Size()] = append(sizeMap[info.Size()], nameInfo.SongName)

		fileInfo, err := file.Info()
		if err != nil {
			fmt.Printf("mv_name:%s 文件信息获取失败 err=%s\n", file.Name(), err.Error())
			continue
		}

		// 获取缓存
		cacheKey := fmt.Sprintf("%s %d %d", file.Name(), fileInfo.ModTime().Unix(), fileInfo.Size())
		fileCache := cacheMap[cacheKey]
		if fileCache == nil {
			videoCodeStr, audioCodeStr, err := animeutl.GetProbeCode(fileFullPath)
			if err != nil {
				fmt.Printf("mv_name:%s err=%s\n", file.Name(), errutl.Cause(err).Error())
				continue
			}
			fileCache = &MVCache{
				VideoCodeStr: videoCodeStr,
				AudioCodeStr: audioCodeStr,
			}
		}

		// 查看视频和音频编码对不对的上
		if nameInfo.VideoCodeStr != fileCache.VideoCodeStr {
			// 视频编码对不上
			fmt.Printf("mv_name:%s %s!=%s\n", file.Name(), nameInfo.VideoCodeStr, fileCache.VideoCodeStr)
		}
		if nameInfo.AudioCodeStr != fileCache.AudioCodeStr {
			// 音频编码对不上
			fmt.Printf("mv_name:%s %s!=%s\n", file.Name(), nameInfo.AudioCodeStr, fileCache.AudioCodeStr)
		}

		mvNameList = append(mvNameList, file.Name())

		// 更新缓存
		cacheMap[cacheKey] = fileCache
	}
	println("code check end!")

	// 更新缓存
	err = goutl.WriteBytesToFile(cacheDir, []byte(goutl.Json(cacheMap)))
	if err != nil {
		println(err.Error())
	}

	println("start name list check!")
	errMVList, err := animeutl.CheckMkvMVList(mvNameList)
	if err != nil {
		panic(err.Error())
	}
	for _, mvName := range errMVList {
		println(mvName)
	}
	println("name list check end!")

	return nil
}
